package com.bjsdzk.collector.rpc;


import cmcciot.onenet.nbapi.sdk.api.online.CreateDeviceOpe;
import cmcciot.onenet.nbapi.sdk.entity.Device;
import cmcciot.onenet.nbapi.sdk.utils.HttpSendCenter;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.bjsdzk.backend.rpc.after.OneNetServiceCollect;
import com.bjsdzk.collector.entity.HttpClientResult;
import com.bjsdzk.collector.entity.onenet.DeviceInfoData;
import com.bjsdzk.collector.entity.onenet.DeviceinfoAdd;
import com.bjsdzk.collector.entity.onenet.OneNetResult;
import com.bjsdzk.collector.utils.HttpClientUtils;
import com.bjsdzk.collector.utils.OkHttpCli;
import com.bjsdzk.collector.utils.TimeUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.vertx.core.json.JsonObject;
import io.vertx.redis.RedisClient;
import okhttp3.*;
import org.apache.tomcat.util.codec.binary.Base64;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.*;

@Service(
        version = "1.0.0",
        timeout = 30000,
        interfaceClass = OneNetServiceCollect.class
)
@Component
public class OneNetCollectService implements OneNetServiceCollect {

    private static Logger logger = LoggerFactory.getLogger(OneNetCollectService.class);
    private static final List<String> kwyapiKey = Arrays.asList("qFutuQ3Lhs0umBxivZcYRt5mdmA=","ncZ0iz7mA=wWcUZPRxiz9=yJwiU=","=tMYXa9pUPumxUVLlguX09pbmi0=");
    private static final String  BASEURL="http://api.heclouds.com/";
    private static final String  DEVICES=BASEURL+"devices/";
    private static final String  LOOKDEVICES="http://api.heclouds.com/devices";
    private static final String  EXECUTEOFFINE=BASEURL+"/nbiot/execute/offline";
    private static final String  EXECUTE="http://api.heclouds.com/nbiot/execute";
    private static final String  NBIOT="http://api.heclouds.com/nbiot";
    private static final String  EXECUTECMDSTATUS=BASEURL+"/nbiot/offline/history/";
    public static final String  ZHUOWEN="ZHUOWEN";
    public static final String  SET_OC="SET-OC";
    public static final String  SET_REALTIME="SET-REALTIME";
    public static final String  GET_REALTIME="GET-REALTIME";
    public static final String  CLOSE_WARN_ALARM="CLOSE-WARN-ALARM";
    public static final String  SET_LEAK="SET-LEAK";
    public static final String  SET_TITLE="SET-TITLE";
    public static final String  SET_ALARM="SET-ALARM";
    public static final String  SET_WARN="SET-WARN";
    public static final String  GET_ALARM="GET-ALARM";
    public static final String  GET_WARN="GET-WARN";
    public static final String  SET_TIME="SET-TIME";
    public static final String  SET_EN_REALTIME="SET-EN-REALTIME";
    public static final String  ONENET_DEVICEID_IMEI="onenet_zhuowen";





    @Autowired
    private OkHttpCli okHttpCli;
    @Autowired
    private OkHttpClient okHttpClient;
    @Autowired
    private RedisClient redis;

    @Override
    public String deviceAdd(String s) {
        logger.info("onenet params deviceAdd:{}", s);
        String result = "";
        try {
            JsonObject params = new JsonObject(s);
            String apiKey = deviceTypeString(params.getString("deviceType"));
            String imei = params.getString("imei");
//            logger.info("onenet params imei:{}", imei);
//            CreateDeviceOpe deviceOpe = new CreateDeviceOpe(apiKey);
//            logger.info("onenet params deviceOpe:{}", deviceOpe);
//            Device device = new Device(params.getString("name"), imei, params.getString("imsi"));
//            logger.info("onenet params device:{}", device.toUrl());
//            result = deviceOpe.operation(device, device.toJsonObject()).toString();
//            logger.info("onenet result deviceAdd:{}", result);

            JsonObject jsonObject = new JsonObject();
            jsonObject.put(imei, params.getString("imsi"));
            JsonObject json = new JsonObject();
            json.put("title", params.getString("name"));
            json.put("desc", params.getString("name"));
            json.put("protocol", "LWM2M");
            json.put("auth_info", jsonObject );
            RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());
            Request request = (new Request.Builder()).url(LOOKDEVICES).header("api-key", apiKey).post(requestBody).build();
            Response response = okHttpClient.newCall(request).execute();
            if (response!=null){
                String st = new String(response.body().bytes(), "utf-8");
                result= new JSONObject(st).toString();
            }else {
                logger.info("onenet result response:{}", response);
            }
            logger.info("onenet result result:{}", result);
            Gson gson = new Gson();
            OneNetResult<DeviceinfoAdd> oneNetResult = gson.fromJson(result, new TypeToken<OneNetResult<DeviceinfoAdd>>() {
            }.getType());
            if (oneNetResult.getErrno() == 0) {
                logger.info("onenet result deviceId:{}", oneNetResult.getData().getDevice_id());
                String device_id = oneNetResult.getData().getDevice_id();
                redis.hset(ONENET_DEVICEID_IMEI, device_id, imei, res -> {

                });
            }
        } catch (Exception e) {
            logger.info("onenet result deviceAdd:{} error:{}", e.getMessage());
        }
        return result;
    }

    @Override
    public String deviceDelete(String s) {
        logger.info("onenet params deviceDelete:{}",s);
        JsonObject params = new JsonObject(s);
        String[] headers=deviceType(params.getString("deviceType"));
        Request.Builder builder = new Request.Builder();
        if (headers != null && headers.length > 0) {
            if (headers.length % 2 == 0) {
                for (int i = 0; i < headers.length; i = i + 2) {
                    builder.addHeader(headers[i], headers[i + 1]);
                }
            } else {
            }

        }
        String deviceId=params.getString("deveiceId");
        Request request = builder.url(DEVICES + deviceId).delete().build();
        String result = okHttpCli.execute(request);
        redis.hdel(ONENET_DEVICEID_IMEI, deviceId, h->{

        });
        logger.info("onenet deviceDelete:{}",result);
        return result;
    }

    @Override
    public String lookDevice(String s) {
        logger.info(s);
        JsonObject params = new JsonObject(s);
        String result = okHttpCli.doGet(DEVICES + params.getString("deveiceId"), deviceType(params.getString("deviceType")));
        logger.info(result);
        return result;
    }

    public OneNetResult getAllDevice(int page) {
//        String result = okHttpCli.doGet(LOOKDEVICES+"?online=true" , deviceType(ZHUOWEN));
        String url=LOOKDEVICES+"?online=true&per_page=100";
        if (page>1){
            url=url+"&page="+page;
        }
        Map<String, String> header = new HashMap<>();
        header.put("api-key", deviceTypeString(ZHUOWEN));
        try {
            HttpClientResult get = HttpClientUtils.doGet(url, header, null);
            if (get.getCode()==200){
                String content=get.getContent();
                Gson gson = new Gson();
                OneNetResult<DeviceInfoData> oneNetResult= gson.fromJson(content,new TypeToken<OneNetResult<DeviceInfoData>>(){}.getType());
                return oneNetResult;
            }else {
                logger.error("code:{},content{}",get.getCode(),get.getContent());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String cmd(String s) {
        String messageId=UUID.randomUUID().toString();
        logger.info("onenet messageId:{},cmd:{}",messageId,s);
        JsonObject params = new JsonObject(s);
        String imei = params.getString("imei");
        String deviceType = params.getString("deviceType");

        String apiKey=deviceTypeString(deviceType);

        if(StringUtils.isEquals(ZHUOWEN,deviceType)) {
            String contentStr=params.getString("content");
            String command=params.getString("command");
            byte[] encMsg = Base64.encodeBase64(contentStr.getBytes());
            String content = new String(encMsg);
            JsonObject pa = new JsonObject();
            pa.put("command", command);
            pa.put("content", content);
            String chec = "join-mcbs&" + content;
            String checMd5 = DigestUtils.md5DigestAsHex(chec.getBytes());
            pa.put("check", checMd5.toUpperCase());
            String args = pa.toString();
            logger.debug("onenet imei:{},messageId:{},args:{}",imei,messageId,args);
//        JSONObject json =new  JSONObject();
//        json.put("args", args);
            return cmdWrite(args, apiKey, imei,messageId);
        }
        return null;
    }

    public String cmdWrite(String args,String apiKey,String imei,String messageId) {
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("res_id", 5750);
        jsonObject.put("val", args);
        jsonArray.put(jsonObject);
        JSONObject data = new JSONObject();
        data.put("data", jsonArray);
        JSONObject post = HttpSendCenter.post(apiKey, toUrl(NBIOT,imei), data);
        logger.info("onenet ,imei:{},messageId:{},cmdWrite:{}",imei,messageId,post.toString());
        return post.toString();
    }

    public String[] deviceType(String deviceType) {
        return new String[]{"api-key", deviceTypeString(deviceType)};
    }

    public String deviceTypeString(String deviceType){
        if(StringUtils.isEquals(deviceType,"SMOKE")){
            return kwyapiKey.get(0);
        }else if(StringUtils.isEquals(deviceType,"GAS")){
            return kwyapiKey.get(0);
        }else if(StringUtils.isEquals(deviceType,"BAREN_SMOKE")){
            return kwyapiKey.get(1);
        }else if(StringUtils.isEquals(deviceType,ZHUOWEN)){
            return kwyapiKey.get(2);
        }
        return null;
    }
    public String executeCmd(String  pa,String imei, String deviceType) throws Exception {
        Map<String,String> header=new HashMap<>();
        String  apiKey=deviceTypeString(deviceType);

        JSONObject json =new  JSONObject();
        json.put("args", pa);
        JSONObject post = HttpSendCenter.post(apiKey, toUrl(EXECUTEOFFINE,imei,"EXECUTEOFFINE"), json);
        logger.info(post.toString());
        return post.toString();
    }

    public String getCmdStatus(String  uuuid,String imei, String deviceType) throws Exception {
        Map<String,String> header=new HashMap<>();
        String  apiKey=deviceTypeString(deviceType);
        JSONObject result = HttpSendCenter.get(apiKey, toUrl(EXECUTECMDSTATUS + uuuid, imei, "EXECUTECMDSTATUS"));
        return result.toString();
    }

    public String toUrl(String ur,String imei,int timeout) {
        String toUrl = toUrl(ur, imei);
        return toUrl+"&timeout="+timeout;
    }


    public String toUrl(String ur,String imei) {
        StringBuilder url = new StringBuilder(ur);
        switch (ur){
            case NBIOT :
                url.append("?imei=").append(imei);
                url.append("&obj_id=").append(3200);
                url.append("&obj_inst_id=").append(0);
                url.append("&res_id=").append(5750);
                url.append("&mode=").append(1);
                url.append("&timeout=").append(10);
                break;
        }

        return url.toString();
    }

    public String toUrl(String ur,String imei,String flag) {
        StringBuilder url = new StringBuilder(ur);
        switch (flag){

            case "EXECUTEOFFINE" :
                url.append("?imei=").append(imei);
                url.append("&obj_id=").append(3200);
                url.append("&obj_inst_id=").append(0);
                url.append("&res_id=").append(5750);
                String time = TimeUtil.parseTime(LocalDateTime.now().plusMinutes(5) , TimeUtil.TimeFormat.LONG_DATE_PATTERN_LINE_T);
                url.append("&expired_time=").append(time);
                break;
            case "EXECUTECMDSTATUS" :
                url.append("?imei=").append(imei);
            case ZHUOWEN :
                url.append("?imei=").append(imei);
                url.append("&obj_id=").append(3200);
                url.append("&obj_inst_id=").append(0);
                url.append("&res_id=").append(5750);
        }

        return url.toString();
    }
}
